package org.mydba.info;

import org.mydba.util.DBAHelper;
import org.mydba.MyDBA;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.Callable;

/**
 * Asynchonous task to retrieve an execution plan from Oracle an store it in the local report database.
 *
 * @see <a href="http://www.techgrasp.com/blogs/sharadjava/java-concurrency-series-how-use-futurefuturetask-and-callable">Java Concurrency Series- How to use Future/FutureTask and Callable</a>
 * @since 1.0
 */
public class ExecutionPlanRetriever implements Callable {
    private String sqlid;
    private int childNumber;
    private int commandType;

    ExecutionPlanRetriever(final String sqlid, final int childNumber, final int commandType) {
        this.sqlid = sqlid;
        this.childNumber = childNumber;
        this.commandType = commandType;
    }

    public Boolean call() throws Exception {
        Connection c = null;
        Connection myDBAConnection = null;
        PreparedStatement pUpdate = null;

        try {
            c = MyDBA.getReportDbConnection();
            myDBAConnection = MyDBA.getConnection();
            final String plan = SnapshotHelper.getExecutionPlan(myDBAConnection, sqlid, childNumber);
            if (plan != null) {
                pUpdate = c.prepareStatement("update sqlplan set plan_text=? where sql_id=? and child_number=?");
                pUpdate.setString(1, plan);
                pUpdate.setString(2, sqlid);
                pUpdate.setInt(3, childNumber);
                pUpdate.executeUpdate();

                if (commandType != 0) {
                    SnapshotHelper.insertExecutionPlanDetails(c, myDBAConnection, sqlid, childNumber);
                }
            }

            c.commit();
        }
        catch( SQLException sqle ) {
            sqle.printStackTrace();
            if( c != null ){
                c.rollback();
            }
            return Boolean.FALSE;
        }
        finally {
            DBAHelper.close(pUpdate);
            DBAHelper.close(c);
            DBAHelper.close(myDBAConnection);
        }

        return Boolean.TRUE;
    }
}
